package com.functest.orm;

/**
 * @author DavydovMD
 * Date: 11.04.13
 *
 * Represent abstract concept of a mapper for concrete entity, such as Database table. It could also be some XML parent tag, or whatever.
 * Not to be used directly. Most important subclasses to date is SingleDbTableMapper
 */
class AbstractTableMapper extends Mapper {
    String tableName

    protected AbstractTableMapper(Mapper mapper, String table, String keyField = mapper.keyField) {
        super(mapper);
        this.tableName = table
        this.keyField = keyField
    }

    protected AbstractTableMapper(MapperFields builder, String table, String keyField = builder.fields.first().name) {
        super(builder);
        this.tableName = table
        this.keyField = keyField
    }

    /**
     * Get first part of fully qualified field name.
     * Note1: Implementation in AbstractTableMapper is meant to be overridden
     * Note2: Entire concept of fully qualified field names is currently not properly implemented or thought out, and will be re-considered!
     * @return
     */
    String getPrefix(){
        tableName + '.'
    }

    /**
     * Kind of short toString equivalent
     * @return
     */
    @Override
    String getName(){
        "AbstractTableMapper $tableName (key:$keyField)"
    }

    /**
     * Get fully qualified field name (including table name). Works only for single-column-sourced fields.
     * Note: Implementation in AbstractTableMapper is a reference one, and is supposed to be overriden
     * @param field field name
     * @return fully qualified name (including parent entity name) or NULL if field is multi-column-sourced
     */
    @Override
    String getFqSourceName(String field) {
        List from = getField(field).from
        if (from.size() != 1) return null
        "${tableName}.${from.last()}"
    }

    /**
     * Get fully qualified names of column fields (works for multi-column-sourced fields as well.
     * Note: Implementation in AbstractTableMapper is a reference one, and is supposed to be overriden
     * @param field  field name
     * @return  Returns map with keys==source column name, value== fully qualified source column name
     */
    @Override
    Map<String, String> getFqSourceNames(String field) {
        Map ret = [:]
        builder.getField(field).from.each { String s ->
            ret.put(s, "${tableName}.${s}" as String)
        }
        ret
    }

}